starter

2019-01-31

Wanted to put together my own type of starter files; gulp, scss -> css, css minified, webpack, babel... new to this so I wanted to try and document my flight down the rabbit hole :D

starter basics

  • make your folder and cd into it.
  • npm init -y sets up your package.json without having to answer 21 Qs about the file. SN: you can always edit it later, don't be scared
  • mkdir two folders: src and public Note: public or dist seem to be what others tend to name it, I think I myself have used both in other projects. Pretty much, it's the folder that will hold files (from src folder) after being compiled/transpiled.

npm or yarn

Use either-- word on the street is yarn is faster-- yarn docs

gulp

Gulp docs

Gulp is on 4, I believe, but you can install another version by npm install gulp@3.9.1 --save-dev or if installing latest npm install gulp -D as it says on the Gulp front page.

gulp --version shows both cli version and local, make sure they both match or restart the process.

Make sure to create gulpfile.js, which is final step on Gulp front page.

gulp file example

Creating tasks and setting up a default declaring tasks to be run in order. Note: Gulp 4 seems to use series and parallel to declare order or what should be ran simultaneously.

const gulp = require('gulp');

gulp.task('printName', function() {
	console.log('jo')
})

gulp.task('printAge', function() {
	console.log('30')
})

gulp.task('default',['printName', 'printAge'])

packages

Whatever you are looking to add you can run a search, example: sass

gulp-sass

gulp-sass

from the docs:

gulp.task('sass', function () {
  return gulp.src('./sass/**/*.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe(gulp.dest('./css'));
});

Running gulp sass returns your scss/sass as css-- later the setup will have everything bundled nicely so essentially you'd be running gulp prompting all tasks to run.

Folder structure atm: public[folder] > css[folder] > scss/sass converted to css output

src[folder] > scss[folder] > your code before it gets transpiled, files you work on

gulp-autoprefixer | vendor prefixes

gulp-autoprefixer

This is a good one to have so you're not worrying about doing things like -webkit-, -moz-, -o-:

given this:

body {
  background: black;
  display: flex;
  flex-direction:  row-reverse; }

autoprefixer outputs:

body {
  background: black;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: reverse;
      -ms-flex-direction: row-reverse;
          flex-direction: row-reverse; }

Note: I came across cascade: false in the usage example of the npm page-- removing that gives the indentation in the example above, if cascade: true, which is default.

watching files in gulp | automatically run tasks

gulp docs - watching files

gulp.task('default',['sass'], function() {
	gulp.watch('./src/scss/**/*', ['sass']);
})

default task; sass-- watching all folders** and files * within the scss folder in src-- if there's a change in any of those specified it will run the sass task

browser sync | auto reload

browsersync docs creates a local server and depending on changes will auto reload.

using with gulp

browserSync.reload | browserSync.stream

gulpfile.js

const gulp = require('gulp');
const sass = require('gulp-sass');
const autoprefixer = require('gulp-autoprefixer');
const browserSync = require('browser-sync');
const reload = browserSync.reload;


// sass
gulp.task('sass', function () {
  return gulp.src('./src/scss/**/*.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe(autoprefixer({
      browsers: ['last 2 versions'],
      // cascade: false
    }))
    .pipe(gulp.dest('./public/css'))
    .pipe(browserSync.stream())
});

// server
gulp.task('browser-sync', function() {
  browserSync.init({
    server: {
      baseDir: "./public",
      notify: false,
      // when true opens new window each 'gulp' run
      open: false
    }
  });
});


gulp.task('default',['sass', 'browser-sync'], function() {
	gulp.watch('./src/scss/**/*', ['sass']);
})

.stream() is called after compiling finishes, it reloads at specific points during tasks and inform browsers of changes.

From the docs: "Because Browsersync only cares about your CSS when it's finished compiling - make sure you call .stream() after gulp.dest"

Note: comment above open: false in example above-- set otherwise will open a new window each time you run gulp

minify css | source maps

gulp-clean-css

minifies files for production--

added npm install gulp-sourcemaps --save-dev for source maps.

What the hell is a source map? source maps

Source maps hold information about original file. Looking for a certain line of JavaScript? A lookup in the source map will return original file.

Basically, it's a way to be able to debug after code has been minified/combined for production. If you've ever seen those files... it might as well be Kryptonian if you're looking for something specific in there.

webpack | babel

start

webpack docs

npm install --save-dev webpack and npm install --save-dev webpack-cli when using webpack 4

webpack.config.js goes in root, create file webpack config

const path = require('path');

module.exports = {
	entry: {
		app: './src/js/components/index.js'
	},

	output: {
		// w.e name ie: app above will be output filename
		filename: '[name].js',
		path: path.resolve(__dirname, 'public/js/components')
	},
}

entry point is where initial code goes; working files. The output will be named, in this case, app.js inside the public/js/components folder. [name] is replaced with whatever key name is used in entry.

the rabbit hole of configuration

babel babel-loader

webpack docs - plugins

commonsChunkPlugin

When you bundle it will snag all imports (and what it entails) plus your code.

If you import something like React all that comes with that import will be bundled.

Note: In Webpack 4, commonsChunkPlugin is deprecated and refers you to use split-chunks-plugin

const webpack = require('webpack');
const path = require('path');

module.exports = {
	entry: {
		comp: './src/js/comp/index.js',
		vendor: ['react']
	},

	output: {
		// w.e name ie: app above will be output filename
		filename: '[name].js',
		path: path.resolve(__dirname, 'public/js/components')
	},

	optimization: {
    splitChunks: {
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendor',
          chunks: 'all',
        },
      }
    }
  },

	module: {
	  rules: [
	    {
	    	test: /\.js$/,
	    	exclude: /node_modules/,
	    	loader: 'babel-loader',
	    	options: {
	    		presets: [ '@babel/preset-env', ],
	    		plugins: [],
	    	}
	    }
	  ]
	},
}

split chunks example used^

The amount of back and forth between webpack docs, babel docs, and related posts... as well as, extra packages to install whether forgotten or unaware until I saw the terminal errors...

many plugins were no longer used so went looking for updated/ alternate version.

Reading this guy's journey was a nice break from troubleshooting: gricard/webpack4upgrade. It showed me I wasn't too far off with my setup, very helpful as well in areas I wasn't to add.

webpack from gulp

Led to gulp-shell package, but noticed people complaining of anti-pattern use, as well as others chiming in on other forums saying it's use was 'blacklisted' so I went looking for an alternative and found gulp-exec -- gulp-exec

gulp-shell drama:

let exec = require('gulp-exec');

// webpack
gulp.task('webpack', function() {
  return gulp.src('*.js', {read: false})
    .pipe(exec('webpack'))
    .pipe(browserSync.stream())
})

[...]

gulp.task('default',['sass', 'webpack', 'browser-sync'], function() {
	gulp.watch('./src/scss/**/*', ['sass'])
  gulp.watch('./src/js/**/*', ['webpack'])
})

with this running gulp will run all tasks included webpack

package.json

 "scripts": {
    "watch": "gulp",
    "production": "gulp production",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

This way I'm able to run my usual npm run watch, which will trigger gulp.


← go back